//***************************************************************************
//*
//*	File:			DialogFolder.cpp
//*	Description:	Folder dialog
//*
//***************************************************************************

//
//--------------------------------------------------------------- PRECOMPILED
//

#include "stdafx.h"

//
//--------------------------------------------------- DECLARATION DEPENDENCIES
//

//
//--------------------------------------------------------------- DECLARATION
//

#include "FolderDialog.h"

//
//--------------------------------------------------- DEFINITION DEPENDENCIES
//

//
//-------------------------------------------------------------- PREPROCESSOR
//

#ifdef	_DEBUG
#define new DEBUG_NEW
#undef	THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//
//---------------------------------------------------------------- DEFINITION
//

//
//---------------------------------------------------------------------------------------------------
//*************************************     CON/DESTRUCTION     *************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					  Constructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Default constructor
//**	@PARM		[in] The title to display
//**	@PARM		[in] The description to display (status text)
//**	@PARM		[in] The initial folder
//**	@PARM		[in] The root folder
//**	@PARM		[in] The brower's style
//**	@PARM		[in] A pointer to the parent window
//**	@END
//***************************************************************************************************
//inline
CFolderDialog::CFolderDialog(		LPCSTR		a_pszTitle			/*= NULL*/									
							,		LPCSTR		a_pszDescription	/*= NULL*/
							,		LPCSTR		a_strInitialPath	/*= NULL*/
							,		LPCSTR		a_strRootPath		/*= NULL*/
							,		DWORD		a_dwStyle			/*= BIF_EDITBOX	| BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS | BIF_USENEWUI	*/						
							,		CWnd*		a_pwndOwner			/*= NULL*/				)			
{
	//
	//	SETUP PATHS
	//
	this->m_pidPath						= NULL;
	this->m_pidRootPath					= this->GetPIDLFromPath( a_strRootPath		);
	this->m_pidInitialPath				= this->GetPIDLFromPath( a_strInitialPath	);

	//
	//	SETUP BROWSE INFO
	//
	this->m_BrowseInfo.hwndOwner		= a_pwndOwner->GetSafeHwnd();
	this->m_BrowseInfo.pidlRoot			= this->m_pidRootPath; 
	this->m_BrowseInfo.lpszTitle		= const_cast< char* > (	( NULL == a_pszDescription	) ? "Please select the location from the list below:"	: a_pszDescription	);//						( NULL == a_pszTitle		) ? "Select Path"										: a_pszTitle		 ; 
	this->m_BrowseInfo.pszDisplayName	= NULL;
	this->m_BrowseInfo.ulFlags			= a_dwStyle; 
	this->m_BrowseInfo.lpfn				= CFolderDialog::S_ReceiveMessage;
	this->m_BrowseInfo.lParam			= NULL;
	this->m_BrowseInfo.iImage			= 0;

	//
	//	CLEAR TEMP VARS
	//
	this->m_hWnd						= NULL;
}

//***************************************************************************************************
//**																					   Destructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Default destructor
//**	@END
//***************************************************************************************************
//inline
CFolderDialog::~CFolderDialog()
{
}

//
//---------------------------------------------------------------------------------------------------
//*****************************************     GET/SET     *****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																						  GetPath
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Retruns the path the user selected
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CString CFolderDialog::GetPath( void ) const 
{
	CString strPath;

	::SHGetPathFromIDList( this->m_pidPath, strPath.GetBuffer( _MAX_PATH ) );

	strPath.ReleaseBuffer();

	return strPath;
//	return this->m_strPath;
}

//***************************************************************************************************
//**																					  GetRootPath
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Retruns the root path
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CString CFolderDialog::GetRootPath( void ) const 
{
	CString strPath;

	::SHGetPathFromIDList( this->m_pidRootPath, strPath.GetBuffer( _MAX_PATH ) );

	strPath.ReleaseBuffer();

	return strPath;
}

//***************************************************************************************************
//**																				   GetInitialPath
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Retruns the initial path
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CString CFolderDialog::GetInitialPath( void ) const 
{
	CString strPath;

	::SHGetPathFromIDList( this->m_pidInitialPath, strPath.GetBuffer( _MAX_PATH ) );

	strPath.ReleaseBuffer();

	return strPath;
}
 
//***************************************************************************************************
//**																					   IsNewStyle
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up to use new style
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::IsNewStyle( void ) const 
{
	return this->HasFlags( BIF_NEWDIALOGSTYLE );
}

//***************************************************************************************************
//**																			  IsBrowseForComputer  
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up to browse for computers
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::IsBrowseForComputer( void ) const 
{
	return this->HasFlags( BIF_BROWSEFORCOMPUTER );
}

//***************************************************************************************************
//**																			   IsBrowseForPrinter
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up to browse for printers
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::IsBrowseForPrinter( void ) const 
{
	return this->HasFlags( BIF_BROWSEFORPRINTER );
}
 
//***************************************************************************************************
//**																						  HasHint
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog has a UA hint
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::HasHint( void ) const 
{
	return this->HasFlags( BIF_UAHINT );
}

//***************************************************************************************************
//**																					   HasEditBox
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog has an edit box
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::HasEditBox( void ) const 
{
	return this->HasFlags( BIF_EDITBOX );
}

//***************************************************************************************************
//**																					HasStatusText
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog has a status text
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::HasStatusText( void ) const 
{
	return this->HasFlags( BIF_STATUSTEXT );
}

//***************************************************************************************************
//**																			   HasNewFolderButton
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog has a "New Folder" button
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::HasNewFolderButton( void ) const 
{
	return this->HasFlags( BIF_NONEWFOLDERBUTTON ) ? FALSE : TRUE;
}

//***************************************************************************************************
//**																					 DoesValidate
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up validate the path(i.e. not return invalid paths)
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::DoesValidate( void ) const 
{
	return this->HasFlags( BIF_VALIDATE );
}

//***************************************************************************************************
//**																				  DoesIncludeURLs
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up include URLs
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::DoesIncludeURLs( void ) const 
{
	return this->HasFlags( BIF_BROWSEINCLUDEURLS );
}

//***************************************************************************************************
//**																				 DoesIncludeFiles  
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up include files
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::DoesIncludeFiles( void ) const 
{
	return this->HasFlags( BIF_BROWSEINCLUDEFILES );
}

//***************************************************************************************************
//**																				DoesIncludeShares	  
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up include shares
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::DoesIncludeShares( void ) const 
{
	return this->HasFlags( BIF_SHAREABLE );
}

//***************************************************************************************************
//**																			 DoesTranslateTargets 
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up to translate targets
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::DoesTranslateTargets( void ) const 
{
	return this->HasFlags( BIF_NOTRANSLATETARGETS ) ? FALSE : TRUE;
}

//***************************************************************************************************
//**																			 DoesNotGoBelowDomain	  
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up to browse below domain level
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::DoesGoBelowDomain( void ) const 
{
	return this->HasFlags( BIF_DONTGOBELOWDOMAIN ) ? FALSE : TRUE;
}

//***************************************************************************************************
//**																	DoesReturnFileSystemAncestors	  
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up to return file system ancestors
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::DoesReturnFileSystemAncestors( void ) const 
{
	return this->HasFlags( BIF_RETURNFSANCESTORS );
}

//***************************************************************************************************
//**																	 DoesReturnOnlyFileSystemDirs			  
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog is set up to return only file system directories
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::DoesReturnOnlyFileSystemDirs( void ) const 
{
	return this->HasFlags( BIF_RETURNONLYFSDIRS );
}
 
//***************************************************************************************************
//**																						 HasFlags
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Determines whether the dialog has the specified flags
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
BOOL CFolderDialog::HasFlags( DWORD a_dwFlags ) const 
{
	return ( this->m_BrowseInfo.ulFlags & a_dwFlags ) ? TRUE : FALSE;
}

//***************************************************************************************************
//***************************************************************************************************
 
//***************************************************************************************************
//**																				   EnableNewStyle
//***************************************************************************************************
//**	@DOC		GET
//**	@MFUNC		Sets the dialog up to use new style
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableNewStyle( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_NEWDIALOGSTYLE );
	}
	else
	{
		this->ModifyFlags( BIF_NEWDIALOGSTYLE, 0 );
	}
}

//***************************************************************************************************
//**																		  EnableBrowseForComputer 
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to browse for computers
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableBrowseForComputer( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_BROWSEFORCOMPUTER );
	}
	else
	{
		this->ModifyFlags( BIF_BROWSEFORCOMPUTER, 0 );
	}
}

//***************************************************************************************************
//**																		   EnableBrowseForPrinter		  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to browse for printers
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableBrowseForPrinter( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_BROWSEFORPRINTER );
	}
	else
	{
		this->ModifyFlags( BIF_BROWSEFORPRINTER, 0 );
	}
}
 
//***************************************************************************************************
//**																					   EnableHint
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to have a UA hint
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableHint( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_UAHINT );
	}
	else
	{
		this->ModifyFlags( BIF_UAHINT, 0 );
	}
}

//***************************************************************************************************
//**																				    EnableEditBox
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to have an edit box
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableEditBox( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_EDITBOX );
	}
	else
	{
		this->ModifyFlags( BIF_EDITBOX, 0 );
	}
}

//***************************************************************************************************
//**																				 EnableStatusText
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to have a status text
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableStatusText( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_STATUSTEXT );
	}
	else
	{
		this->ModifyFlags( BIF_STATUSTEXT, 0 );
	}
}

//***************************************************************************************************
//**																			EnableNewFolderButton  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to hava a "New Folder" button
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableNewFolderButton( BOOL a_bEnable ) 
{
	if ( FALSE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_NONEWFOLDERBUTTON );
	}
	else
	{
		this->ModifyFlags( BIF_NONEWFOLDERBUTTON, 0 );
	}
}
 
//***************************************************************************************************
//**																				   EnableValidate
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to validate the path(i.e. not return invalid paths)
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableValidate( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_VALIDATE );
	}
	else
	{
		this->ModifyFlags( BIF_VALIDATE, 0 );
	}
}

//***************************************************************************************************
//**																				EnableIncludeURLs  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to include URLs
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableIncludeURLs( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_BROWSEINCLUDEURLS );
	}
	else
	{
		this->ModifyFlags( BIF_BROWSEINCLUDEURLS, 0 );
	}
}

//***************************************************************************************************
//**																			   EnableIncludeFiles	  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to include files
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableIncludeFiles( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_BROWSEINCLUDEFILES );
	}
	else
	{
		this->ModifyFlags( BIF_BROWSEINCLUDEFILES, 0 );
	}
}

//***************************************************************************************************
//**																			  EnableIncludeShares  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to include shares
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableIncludeShares( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_SHAREABLE );
	}
	else
	{
		this->ModifyFlags( BIF_SHAREABLE, 0 );
	}
}

//***************************************************************************************************
//**																		   EnableTranslateTargets  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to translate targets
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableTranslateTargets( BOOL a_bEnable ) 
{
	if ( FALSE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_NOTRANSLATETARGETS );
	}
	else
	{
		this->ModifyFlags( BIF_NOTRANSLATETARGETS, 0 );
	}
}

//***************************************************************************************************
//**																			  EnableGoBelowDomain		  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to browse below domain level
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableGoBelowDomain( BOOL a_bEnable ) 
{
	if ( FALSE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_DONTGOBELOWDOMAIN );
	}
	else
	{
		this->ModifyFlags( BIF_DONTGOBELOWDOMAIN, 0 );
	}
}

//***************************************************************************************************
//**																  EnableReturnFileSystemAncestors	  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to return file system ancestors
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableReturnFileSystemAncestors( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_RETURNFSANCESTORS );
	}
	else
	{
		this->ModifyFlags( BIF_RETURNFSANCESTORS, 0 );
	}
}

//***************************************************************************************************
//**																   EnableReturnOnlyFileSystemDirs			  
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the dialog up to return only file system directories
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableReturnOnlyFileSystemDirs( BOOL a_bEnable ) 
{
	if ( TRUE == a_bEnable )
	{
		this->ModifyFlags( 0, BIF_RETURNONLYFSDIRS );
	}
	else
	{
		this->ModifyFlags( BIF_RETURNONLYFSDIRS, 0 );
	}
}
 
//***************************************************************************************************
//**																					  SetRootPath
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the root path
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::SetRootPath( LPITEMIDLIST a_pidPath ) 
{
	this->m_pidRootPath	= a_pidPath;
}

//***************************************************************************************************
//**																					  SetRootPath
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the root path
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::SetRootPath( const CString& a_strPath ) 
{
	this->m_pidRootPath	= this->GetPIDLFromPath( a_strPath );
}

//***************************************************************************************************
//**																				   SetInitialPath
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the initial path
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::SetInitialPath( LPITEMIDLIST a_pidPath ) 
{
	this->m_pidInitialPath = a_pidPath;
}

//***************************************************************************************************
//**																				   SetInitialPath
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Sets the initial path
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::SetInitialPath( const CString& a_strPath ) 
{
	this->m_pidInitialPath	= this->GetPIDLFromPath( a_strPath );
}
 
//***************************************************************************************************
//**																					  ModifyFlags
//***************************************************************************************************
//**	@DOC		SET
//**	@MFUNC		Modifies the dialog's flags	
//**	@RDESC	
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::ModifyFlags( DWORD a_dwRemove, DWORD a_dwAdd ) 
{
	this->m_BrowseInfo.ulFlags &= ~a_dwRemove	;
	this->m_BrowseInfo.ulFlags |=  a_dwAdd		;
}

//
//---------------------------------------------------------------------------------------------------
//***************************************     INFORMATION     ***************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				  GetPIDLFromPath
//***************************************************************************************************
//**	@DOC		INFORMATION
//**	@MFUNC		Determines the item id list for the specified path
//**	@END
//***************************************************************************************************
//inline
LPITEMIDLIST CFolderDialog::GetPIDLFromPath( LPCSTR a_pszPath )			
{
	//
	//	CHECK VALIDITY
	//
	if ( NULL == a_pszPath )
	{
		return NULL;
	}

	//
	//	GET DESKTOP FOLDER
	//
	CComPtr< IShellFolder > pIShellFolder = NULL;

	::SHGetDesktopFolder( &pIShellFolder );

	if ( TRUE == pIShellFolder.IsEqualObject( NULL )  )
	{
		return NULL;
	}

	//
	//	CONVERT TO OLE STRING
	//
	OLECHAR			polePath		[ _MAX_PATH ];

	::MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, a_pszPath, -1, polePath, _MAX_PATH * sizeof( OLECHAR ) );

	//
	//	GET DISPLAY NAME
	//
	ULONG			ulEaten			= 0;
	DWORD			dwAttributes	= 0;
	LPITEMIDLIST	pidl			= NULL;
	HRESULT			hResult			= pIShellFolder->ParseDisplayName( this->m_BrowseInfo.hwndOwner, NULL, polePath, &ulEaten, &pidl, &dwAttributes );

	//
	//	RETURN RESULT
	//
	return pidl;
}

//
//---------------------------------------------------------------------------------------------------
//**************************************     MODIFICATION     ***************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																						 EnableOK
//***************************************************************************************************
//**	@DOC		MODIFICATION
//**	@MFUNC		Enables or disables the OK button
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::EnableOK( BOOL a_bEnable ) 
{
	::SendMessage( this->m_hWnd, BFFM_ENABLEOK, 0, a_bEnable );
}

//***************************************************************************************************
//**																					 SetSelection	 
//***************************************************************************************************
//**	@DOC		MODIFICATION
//**	@MFUNC		Selects the specified folder
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::SetSelection( LPCITEMIDLIST a_pidPath ) 
{
	::SendMessage( this->m_hWnd, BFFM_SETSELECTION, FALSE, reinterpret_cast< LPARAM > (a_pidPath) );
}

//***************************************************************************************************
//**																					 SetSelection	 
//***************************************************************************************************
//**	@DOC		MODIFICATION
//**	@MFUNC		Selects the specified folder
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::SetSelection( LPCSTR a_pszPath ) 
{
	::SendMessage( this->m_hWnd, BFFM_SETSELECTION, TRUE, reinterpret_cast< LPARAM > (a_pszPath) );
}

//***************************************************************************************************
//**																					SetStatusText	 
//***************************************************************************************************
//**	@DOC		MODIFICATION
//**	@MFUNC		Sets the specified status text
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::SetStatusText( LPCSTR a_pszText ) 
{
	::SendMessage( this->m_hWnd, BFFM_SETSTATUSTEXT, 0, reinterpret_cast< LPARAM > (a_pszText) );
}

//
//---------------------------------------------------------------------------------------------------
//****************************************     EXECUTION     ****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																						  DoModal
//***************************************************************************************************
//**	@DOC		EXECUTION
//**	@MFUNC		Runs the modal loop
//**	@RDESC		<t IDOK> if successful, <t IDCANCEL> otherwise.
//**	@END
//***************************************************************************************************
//inline
UINT CFolderDialog::DoModal( void )
{
	//
	//	INVALIDATE WINDOW HANDLE
	//
	this->m_hWnd = NULL;

	//
	//	FILL IN BROWSE INFO
	//
	this->m_BrowseInfo.lParam			= reinterpret_cast< LPARAM > (this);
	this->m_BrowseInfo.pszDisplayName	= this->m_strPath.GetBuffer( _MAX_PATH );

	//
	//	BROSE FOR FOLDER
	//
	this->m_pidPath = ::SHBrowseForFolder( &this->m_BrowseInfo );

	//
	//	INVALIDATE BROWSE INFO
	//
	this->m_BrowseInfo.lParam			= NULL;
	this->m_BrowseInfo.pszDisplayName	= NULL;

	//
	//	RELEASE BUFFER
	//
	this->m_strPath.ReleaseBuffer();

	//
	//	INVALIDATE WINDOW HANDLE
	//
	this->m_hWnd = NULL;

	//
	//	RETURN RESULT
	//
	return ( NULL == this->m_pidPath ) ? IDCANCEL : IDOK;
}

//
//---------------------------------------------------------------------------------------------------
//****************************************     CALLBACKS     ****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				 S_ReceiveMessage
//***************************************************************************************************
//**	@DOC		CALLBACKS
//**	@MFUNC		Receives a message from the browse actual dialog
//**	@END
//***************************************************************************************************
//inline
int CALLBACK CFolderDialog::S_ReceiveMessage( HWND a_hWnd, UINT a_uiMsg, LPARAM a_lParam, LPARAM a_pData ) 
{
	//
	//	GET THIS POINTER
	//
	CFolderDialog* pThis = reinterpret_cast< CFolderDialog* > (a_pData);

	//
	//	STORE WINDOW HANDLE
	//
	pThis->m_hWnd = a_hWnd;

	//
	//	PASS ON
	//
	switch ( a_uiMsg )
	{
		case BFFM_INITIALIZED	:	pThis->OnInitialized	()													; break;
		case BFFM_SELCHANGED	:	pThis->OnSelChanged		( reinterpret_cast< LPCITEMIDLIST > (a_lParam) )	; break;
		case BFFM_VALIDATEFAILED:	pThis->OnValidateFailed	( reinterpret_cast< LPCSTR		  > (a_lParam) )	; break;
	}

	//
	//	RETURN SUCCESS
	//
	return 0;
}

//
//---------------------------------------------------------------------------------------------------
//****************************************     VIRTUALS     *****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					OnInitialized
//***************************************************************************************************
//**	@DOC		VIRTUALS
//**	@MFUNC		Called when the dialog has been initialized
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::OnInitialized( void ) 
{
	//
	//	SELECT THE INITIAL FOLDER
	//
	this->SetSelection( this->m_pidInitialPath );
}

//***************************************************************************************************
//**																					 OnSelChanged
//***************************************************************************************************
//**	@DOC		VIRTUALS
//**	@MFUNC		Called when the selection changed
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::OnSelChanged( LPCITEMIDLIST a_pidSelected ) 
{
}

//***************************************************************************************************
//**																				 OnValidateFailed
//***************************************************************************************************
//**	@DOC		VIRTUALS
//**	@MFUNC		Called when the validation of the current path failed
//**	@END
//***************************************************************************************************
//inline
void CFolderDialog::OnValidateFailed( LPCSTR a_pszName ) 
{
}

/*
function SHGetIDListFromPath(Path: TFileName; var ShellFolder: IShellFolder): pItemIDList; 
var TempPath, NextDir: TFileName; 
    SlashPos: Integer; 
    Folder, subFolder: IShellFolder; 
    PIDL, PIDLbase: PItemIDList; 
    ParseStruct: TStrRet; 
    ParseNAme: string; 
    EList: IEnumIDList; 
    DidGet: integer; 
    ScanParam: integer; 
begin 
  SHGetDesktopFolder(Folder); 
  SHGetSpecialFolderLocation(0, CSIDL_DRIVES, PIDLbase); 

  OLECheck(Folder.BindToObject(PIDLbase, nil, IID_IShellFolder, Pointer(SubFolder))); 
  TempPath := Path; 
  NextDir := ''; 

  { Enumerate the path one directory at a time } 
  while Length(TempPath)>0 do 
  begin 
    SlashPos := Pos('\', TempPath); 
    if SlashPos > 0 then 
    begin 
      if Pos(':', TempPath) > 0 then NextDir := Copy(TempPath, 1, 3) 
      else NextDir := SlashDirName(NextDir) + Copy(TempPath, 1, SlashPos - 1); 
      TempPath := Copy(TempPath, SlashPos + 1, Length(TempPath)); 
    end else begin 
      if NextDir = '' then NextDir:=TempPath 
      else NextDir := SlashDirName(NextDir) + TempPath; 
      TempPath := ''; 
    end; 

    Pidl := PidlBase; 
    ScanParam := SHCONTF_FOLDERS or SHCONTF_INCLUDEHIDDEN; 
    if (NextDir = Path) and (not DirectoryExists(Path)) 
      ScanParam := ScanParam or SHCONTF_NONFOLDERS; 

    if S_OK = SubFolder.EnumObjects(0, ScanParam, EList) then 
      while S_OK = EList.Next(1, pidl, DidGet) do 
      begin 
        OLECheck(SubFolder.GetDisplayNameOf(PIDL, SHGDN_FORPARSING, ParseStruct)); 
        case ParseStruct.uType of 
          STRRET_CSTR: ParseName := ParseStruct.cStr; 
          STRRET_WSTR: ParseName := WideCharToString(ParseStruct.pOleStr); 
          STRRET_OFFSET: Parsename := PChar(DWORD(Pidl)+ParseStruct.uOffset); 
        end; 
        if UpperCase(Parsename) = UpperCase(NextDir) then Break; 
      end else begin 
        Folder:=nil; 
        Result:=nil; 
        Exit; 
      end; 

      if DidGet=0 then 
      begin 
        Folder := nil; 
        Result := nil; 
        Exit; 
      end; 
      PIDLBase := Pidl; 
      Folder := subFolder; 

      { As best as we can, determine whether or not this is a file.       } 
      { If so then we cannot bind it to the ShellFolder (hence "folder".) } 
      if not FileExists(NextDir) then 
        OLECheck(Folder.BindToObject(Pidl, nil, IID_IShellFolder, Pointer(SubFolder))); 
    end; 

  ShellFolder := Folder; 
  if ShellFolder = nil then Result := nil 
  else Result := Pidl; 
end; 

function SlashDirName(ADir: String): string; 
var s: string; 
    RootDir: Boolean; 
begin 
  if ADir <> '' then 
  begin 
    s := ADir; 
    RootDir := ((Length(s) = 3) and (S[2] = ':')) or (s = '\'); 
    if not RootDir then 
      if s[Length(s)] <> '\' then s := s + '\'; 
    Result := s; 
  end; 
end; 

*/